

MAP:
  PUSH(FP);
  MOV(FP,SP);
  PUSH(R1); //save register


  MOV(R1, FPARG(1)); //R1 = n 
  INCR(R1);
  CMP(IND(FPARG(2)), T_CLOSURE);
  JUMP_NE(TYPE_ERROR);
//TYPE CHECK LOOP
MAP_PAIR_LOOP:
  CMP(IND(FPARG(R1)),T_PAIR);
  JUMP_NE(TYPE_ERROR);
  DECR(R1);
  CMP(R1,2);
  JUMP_GT(MAP_PAIR_LOOP);
//CHECK STOP CONDITION
  CMP(INDD(FPARG(3),2),2);
  JUMP_EQ(MAP_RET);

//RECURSIVE CALL ON CDR
  MOV(R1, FPARG(1)); //R1 = n 
  INCR(R1);
MAP_RECURSIVE_PARAM:
  PUSH(INDD(FPARG(R1),2)); //PUSH CDR
  DECR(R1);
  CMP(R1,2);
  JUMP_GT(MAP_RECURSIVE_PARAM);
  PUSH(FPARG(2)); //PUSH PROC
  PUSH(FPARG(1)); //PUSH N
  PUSH(0); //PUSH ENV
  CALL(MAP);
  DROP(FPARG(1)+2);
  PUSH(R0);


MAP_CAR:
//EXTRACT FROM LIST TO STACK
  MOV(R1, FPARG(1)); //R1 = n 
  INCR(R1);
  PUSH(T_FRAME_END); //magic number
MAP_PARAM_PUSH_LOOP:
  PUSH(INDD(FPARG(R1),1)); //PUSH CAR
  DECR(R1);
  CMP(R1,2);
  JUMP_GT(MAP_PARAM_PUSH_LOOP);
  PUSH(FPARG(1)-1); //PUSH N-1
  PUSH(INDD(FPARG(2),1)); //PUSH ENV
  CALLA(INDD(FPARG(2),2));
  DROP(FPARG(1)+1+1);
  PUSH(R0);
  CALL(MAKE_SOB_PAIR);
  DROP(2);
  POP(R1);
  POP(FP);
  RETURN;
MAP_RET:

  PUSH(2);
  JUMP(MAP_CAR);
